﻿namespace SubhadraSolutions.Sharp.Utils.Windows
{
    using System;
    using System.Windows.Threading;

    using SubhadraSolutions.Sharp.Utils.Threading;
    using SubhadraSolutions.Sharp.Utils.Validation;

    /// <summary>
    /// The WindowsDispatcherAdapter class.
    /// </summary>
    public class WindowsDispatcherAdapter : IDispatcher
    {
        /// <summary>
        /// The dispatcher reference
        /// </summary>
        private readonly WeakReference dispatcherReference;

        /// <summary>
        /// Initializes a new instance of the <see cref="WindowsDispatcherAdapter"/> class.
        /// </summary>
        /// <param name="dispatcher">The dispatcher.</param>
        public WindowsDispatcherAdapter(Dispatcher dispatcher)
        {
            Guard.ArgumentNotNull(dispatcher, "dispatcher");
            this.dispatcherReference = new WeakReference(dispatcher);
        }

        /// <summary>
        /// Dispatches the specified action.
        /// </summary>
        /// <param name="action">The action.</param>
        public void Dispatch(Action action)
        {
            var dispatcher = (Dispatcher)this.dispatcherReference.Target;
            if (dispatcher == null || dispatcher.HasShutdownStarted || dispatcher.HasShutdownFinished)
            {
                return;
            }

            if (dispatcher.CheckAccess())
            {
                dispatcher.Invoke(action, DispatcherPriority.Send);
            }
            else
            {
                dispatcher.InvokeAsync(action, DispatcherPriority.Send);
            }
        }
    }
}
